package com.jxzn.locust.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;

import lombok.Data;
import lombok.EqualsAndHashCode;

@Data
@EqualsAndHashCode(callSuper = false)
@MappedSuperclass
public abstract class AbstractTreeableModel extends AbstractModel implements Comparable<AbstractTreeableModel> {
    /**
    * 
    */
    private static final long serialVersionUID = 1L;
    /** 编号 */
    String code;
    /** 名称 */
    String name;
    /** 父类 */
    String parentCode;

    @Transient
    List<AbstractTreeableModel> children;

    @Transient
    Map<String, AbstractTreeableModel> childrenMap;

    public static <T extends AbstractTreeableModel> List<T> toTree(List<T> itemList) {
        List<T> resultList = new ArrayList<T>();
        Map<String, T> map = new HashMap<String, T>();
        itemList.forEach(item -> {
            item.setChildren(new ArrayList<>());
            map.put(item.getCode(), item);

        });
        itemList.forEach(item -> {
            if (map.containsKey(item.getParentCode())) {
                map.get(item.getParentCode()).getChildren().add(item);
            }
        });
        itemList.forEach(item -> {
            if (item.getParentCode().equals("0")) {
                resultList.add(item);
            }
        });
        Collections.sort(resultList);
        return resultList;
    }

    public static <T extends AbstractTreeableModel> Map<String, T> toTreeMap(List<T> itemList) {
        Map<String, T> result = new TreeMap<String, T>();
        Map<String, T> map = new HashMap<String, T>();
        itemList.forEach(item -> {
            item.setChildrenMap(new TreeMap<String, AbstractTreeableModel>());
            map.put(item.getCode(), item);

        });
        itemList.forEach(item -> {
            if (map.containsKey(item.getParentCode())) {
                map.get(item.getParentCode()).getChildrenMap().put(item.getCode(), item);
            }
        });
        itemList.forEach(item -> {
            if (item.getParentCode().equals("0")) {
                result.put(item.getCode(), item);
            }
        });
        return result;
    }

    @Override
    public int compareTo(AbstractTreeableModel o) {
        return this.getCode().compareTo(o.getCode());
    }
}
